package com.ai.platform.core.annotation.aop;

import com.ai.platform.common.util.AiPlatformUtil;
import com.ai.platform.common.util.JDBCUtil;
import com.ai.platform.core.annotation.LogService;
import com.ai.platform.core.enums.LogType;
import com.ai.platform.core.log.LogManager;
import com.ai.platform.model.dto.Input;
import com.ai.platform.model.dto.Output;
import com.ai.platform.system.entity.SysOperationLog;
import com.ai.platform.system.entity.SysUser;
import com.ai.platform.system.service.ISysOperationLogService;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimerTask;

/**
 * @Auther: yeyingsheng
 * @Date: 2018/5/26 20:49
 * @Description: 日志记录
 */
@Aspect
@Component
public class LogAop {

    private Logger logger = LoggerFactory.getLogger(LogAop.class);

    @Pointcut(value = "@annotation(com.ai.platform.core.annotation.LogService)")
    public void cutService() {
    }

    @Around("cutService()")
    public Object doService(ProceedingJoinPoint point) throws Throwable {
        //先执行业务
        Object result = point.proceed();
        try {
            afterHandle(point);
        } catch (Exception e) {
            logger.error("日志记录出错!", e);
        }

        return result;

    }

    private void afterHandle(ProceedingJoinPoint point) throws NoSuchMethodException {
        //获取拦截的方法名
        Signature signature = point.getSignature();
        MethodSignature methodSignature;
        if (!(signature instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        methodSignature = (MethodSignature) signature;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        String methodName = currentMethod.getName();
        //获取注解
        LogService logService = currentMethod.getAnnotation(LogService.class);
        if (null != logService) {
            //拦截方法的参数
            Output output = null;
            Input input = null;
            String className = point.getTarget().getClass().getName();
            Object[] params = point.getArgs();
            for (Object object : params) {
                if (object instanceof Output) {
                    output = (Output) object;
                }
                if (object instanceof Input) {
                    input = (Input) object;
                }
            }
            if (input == null) {
                throw new IllegalArgumentException("input参数为空");
            }
            SysUser sysUser= (SysUser) AiPlatformUtil.getSessionObj(input,SysUser.class);
            if (null == sysUser) {
                throw new IllegalArgumentException("登录校验错误");
            }
            String desc = logService.desc();
            //请求参数
            String optParams = JSON.toJSONString(input);
            optParams = StringUtils.isNotBlank(optParams) && optParams.length() > 3000 ? (optParams.substring(0, 3000) + "...") : optParams;
            String optResult = null != output ? JSON.toJSONString(output) : null;
            optResult = null != optResult && optResult.length() > 3000 ? (optResult.substring(0, 3000) + "...") : optResult;
            List<Object> objectList=new ArrayList<>();
            operationLog.setUserId(sysUser.getId());
            operationLog.setCreateTime(new Date());
            operationLog.setLogClass(className);
            operationLog.setLogMethod(methodName);
            operationLog.setOptParams(optParams);
            operationLog.setOptResult(optResult);
            operationLog.setDesc(desc);
            operationLog.setLogType(LogType.BUSSINESS.getMessage());
            LogManager.getInstance().executeLog(new TimerTask() {
                @Override
                public void run() {
                    JDBCUtil jdbcUtil=new JDBCUtil();
                    try {
                        jdbcUtil.executeUpdate("insert into ",objectList);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    //iSysOperationLogService.insert(operationLog);
                }
            });
        }
    }

}
